﻿

#include "sprite.h"



#pragma warning(push)
#pragma warning(disable : 4290)


namespace d3dx9_dynamic_load
{

	ID3DXSprite* CreateSprite(IDirect3DDevice9* const device,
					CD3DX9_Dll_Loader* const loader)  throw(HRESULT)
	{

		ID3DXSprite* res = NULL;

		HRESULT hr = loader->D3DXCreateSprite(device, &res);
		if FAILED(hr)
		{
			assert(hr>=0 && " failed operation create sprite ");
			throw(hr);
		}



		assert(res);
		return res;
	}


	// Sprite::Sprite


}


//==================================================================
// ======================  test code  ==============================
//==================================================================

#ifdef __USE_TEST_D3DX9LOADER_SPRITE_CLASS__

 
#include <d3d9.h>
#pragma comment (lib,"d3d9.lib")

#define TEST_APPL_WIND_TITLE  L"Sample"

namespace d3dx9_dynamic_load
{

	namespace test
	{

 

		//-----------------------------------------------------------------------------
		// Global variables
		//-----------------------------------------------------------------------------
		LPDIRECT3D9         g_pD3D = NULL; // Used to create the D3DDevice
		LPDIRECT3DDEVICE9   g_pd3dDevice = NULL; // Our rendering device
		CD3DX9_Dll_Loader* g_loader = NULL;
		d3dx9_dynamic_load::Sprite* g_sprite;
		LPDIRECT3DTEXTURE9 g_pHudTexture = NULL;

		// g_mousexPos g_mouseyPos
		static float g_mousexPos = 0.0f;  
		static float g_mouseyPos = 0.0f;


		static HRESULT OnCreateDevice(HWND hWnd, IDirect3DDevice9* device )
		{
			HRESULT hr=0;




			return hr;
		}

		static void OnDestroyDevice()
		{
			//assert(false);

			if(g_sprite)
			{
				delete g_sprite;
				g_sprite = NULL;
			}

			if(g_pHudTexture)
			{
				g_pHudTexture->Release();
				g_pHudTexture = NULL;
			}
		}


		static HRESULT RecreateDevice(HWND hWnd )
		{
			HRESULT hr=0;

			if(g_pd3dDevice)
			{
				OnDestroyDevice();
				g_pd3dDevice->Release();
				g_pd3dDevice = NULL;
			}

			WINDOWINFO wi;
			::GetWindowInfo(hWnd, &wi);


			D3DPRESENT_PARAMETERS d3dpp;
			ZeroMemory( &d3dpp, sizeof( d3dpp ) );
			d3dpp.Windowed = TRUE;
			d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
			d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
			d3dpp.BackBufferWidth  = wi.rcClient.right-wi.rcClient.left;
			d3dpp.BackBufferHeight = wi.rcClient.bottom-wi.rcClient.top;
 
			if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
				hWnd,

				D3DCREATE_HARDWARE_VERTEXPROCESSING, //D3DCREATE_SOFTWARE_VERTEXPROCESSING,

				&d3dpp, &g_pd3dDevice ) ) )
			{
				return E_FAIL;
			}

			hr |= OnCreateDevice(hWnd, g_pd3dDevice);


			assert(hr==0);
			return hr;
		}



		static HRESULT InitD3D( HWND hWnd )
		{
			HRESULT hr=0;
			// Create the D3D object, which is needed to create the D3DDevice.
			if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
				return E_FAIL;
 
			g_loader = new CD3DX9_Dll_Loader();

			hr |= RecreateDevice(hWnd);

			return S_OK;
		}



		static VOID Cleanup()
		{
			if( g_pd3dDevice != NULL )
			{
				OnDestroyDevice();
				g_pd3dDevice->Release();
				g_pd3dDevice = NULL;
			}

			if( g_pD3D != NULL )
				g_pD3D->Release();


			delete g_loader;
		}




		static VOID Render(IDirect3DDevice9* device)
		{
			HRESULT hr =0;
			static int count =0;

			if( NULL == g_pd3dDevice )
				return;

			// Clear the backbuffer to a blue color
			hr |= device->Clear( 0, 

				NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ),

				1.0f, 0 );



			if(g_sprite==NULL)
			{
				//d3dx9_dynamic_load::font_create_options opt;
				g_sprite = new d3dx9_dynamic_load::Sprite(device, g_loader);
			}

			if(!g_pHudTexture)
			{
				hr |= g_loader->D3DXCreateTextureFromFileA(device,
					"j:/d3dx9_dynamic_load/d3dx9-dynamic-load/media/hud.dds", 
					&g_pHudTexture	);

				assert( hr==0 && " need a correct texture path " );
			}



			// Begin the scene
			if( SUCCEEDED( device->BeginScene() ) )
			{
				// Rendering of scene objects can happen here

				if(!g_sprite)
				{
					g_sprite = new d3dx9_dynamic_load::Sprite( device, g_loader);
				}


				// draw in 3d space
				{



				}
				//
				// end


				// draw in screen space
				{
					  hr |= g_sprite->m_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
					 RECT rec = { 30,30, 128, 128  };
						  // g_pHudTexture
					     // (THIS_ LPDIRECT3DTEXTURE9 pTexture, CONST RECT *pSrcRect,
					 //CONST D3DXVECTOR3 *pCenter, 
					 //CONST D3DXVECTOR3 *pPosition, D3DCOLOR Color)
					  D3DXVECTOR3 Center = D3DXVECTOR3(0,0,0);  
					  D3DXVECTOR3 Position = D3DXVECTOR3(g_mousexPos, g_mouseyPos, 0);
								
					 hr |= g_sprite->m_pSprite->Draw( 
						 g_pHudTexture,	&rec,&Center, &Position,
						 0xffffffff						 
						 );
					 hr |=  g_sprite->m_pSprite->End();
				}
				//
				// end

				// render code
				//assert(false);




				// End the scene
				device->EndScene();
			}

			// Present the backbuffer contents to the display
			hr |= device->Present( NULL, NULL, NULL, NULL );


			count++;
			assert(hr==0);

		}




		static LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
		{



			switch( msg )
			{
			case WM_DESTROY:
				Cleanup();
				PostQuitMessage( 0 );
				return 0;

			case WM_PAINT:
				Render(g_pd3dDevice);
				ValidateRect( hWnd, NULL );
				return 0;


			case WM_SIZE:
				RecreateDevice(hWnd);


				break;


			case WM_MOUSEMOVE:	
				g_mousexPos = (float)(  LOWORD(lParam));   // horizontal position 
				g_mouseyPos = (float)(  HIWORD(lParam));   // vertical position 

				break;
			}

			return DefWindowProc( hWnd, msg, wParam, lParam );
		}



		int do_test_sprite_draw()
		{
 

			using namespace d3dx9_dynamic_load::test;
			//UNREFERENCED_PARAMETER( hInst );
//			HINSTANCE   hInst;

			// Register the window class
			WNDCLASSEXW wc =
			{
				sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
				GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
				TEST_APPL_WIND_TITLE, NULL
			};

			RegisterClassExW( &wc );

			// Create the application's window
			HWND hWnd = CreateWindowW( TEST_APPL_WIND_TITLE,  TEST_APPL_WIND_TITLE ,
				WS_OVERLAPPEDWINDOW, 100, 100, 800, 600,
				NULL, NULL, wc.hInstance, NULL );

			// Initialize Direct3D
			if( SUCCEEDED( InitD3D( hWnd ) ) )
			{
				// Show the window
				ShowWindow( hWnd, SW_SHOWDEFAULT );
				UpdateWindow( hWnd );

				// Enter the message loop
				MSG msg;
				while( GetMessage( &msg, NULL, 0, 0 ) )
				{
					TranslateMessage( &msg );
					DispatchMessage( &msg );
				}
			}

			UnregisterClassW( TEST_APPL_WIND_TITLE , wc.hInstance );
			return 0;

 
			//assert(   false &&  " defination __USE_TEST_D3DX9LOADER_SPRITE_CLASS__ not found ");
			//	for test code defination __USE_TEST_D3DX9LOADER_SPRITE_CLASS__ most be defined !
 


		}




	}
}

#ifdef   __USE_TEST_D3DX9LOADER_SPRITE_CLASS__
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
	return d3dx9_dynamic_load::test::do_test_sprite_draw();
}
#endif 



#undef TEST_APPL_WIND_TITLE 

#endif // #ifdef   __USE_TEST_D3DX9LOADER_SPRITE_CLASS__



#pragma warning(pop)
